package xyz.zchao.blog.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.json.JsonMapper;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtException;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import xyz.zchao.blog.annotation.IgnoreToken;
import xyz.zchao.blog.exception.CustomizeException;
import xyz.zchao.blog.pojo.User;
import xyz.zchao.blog.util.JwtTokenUtil;
import xyz.zchao.blog.util.ResultCode;
import xyz.zchao.blog.util.ResultVO;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Method;
import java.security.SignatureException;
import java.util.Arrays;
import java.util.Map;

/**
 * Token验证拦截器
 */
public class TokenValidationInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取token
        String access_token = request.getHeader("Authorization");

        if (!(handler instanceof HandlerMethod)) {  //不是请求接口方法的放行
            return true;
        }

        //获取拦截接方法的实例
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        //判断拦截方法是否存在IgnoreToken注解，存在就忽略token验证，放行请求
        if (method.isAnnotationPresent(IgnoreToken.class)) {
            return true;
        }

        //token 为空，抛出用户未登录异常
        if (access_token == null) {
            throw new CustomizeException(ResultCode.USER_NOT_LOGGED_IN);
        }
        //校验token
        try {
            Claims claims = JwtTokenUtil.parseToken(access_token);
            Integer userId = (Integer) claims.get("userId");
            Integer roleId = (Integer) claims.get("roleId");
            request.setAttribute("userId", userId);
            request.setAttribute("roleId", roleId);
        } catch (ExpiredJwtException e) {   //token过期
            throw new CustomizeException(ResultCode.TOKEN_EXPIRED);
        } catch (JwtException e) {  //其他异常，比如token验证失败，token被篡改等
            throw new CustomizeException(ResultCode.TOKEN_INVALID);
        }
        //通过token验证
        return true;
    }

}
